package vn.vfriends.games.servlet;

import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.openid4java.discovery.DiscoveryInformation;
import org.openid4java.message.AuthRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import vn.vfriends.games.jpa.entity.Role;
import vn.vfriends.games.openid.OpenIdConsumer;
import vn.vfriends.games.service.RoleService;
import vn.vfriends.games.service.UserService;
import vn.vfriends.id.ws.User;

/**
 *
 * @author tuan@vfriends.vn
 */
@WebServlet(name = "openIdConsumerServlet", urlPatterns = {"/opconsumer"})
public class OpenIdConsumerServlet extends HttpServlet {

    private static Logger logger = LoggerFactory.getLogger(OpenIdConsumerServlet.class);
    
    private static String returnToUrl = OpenIdConsumer.getReturnToUrl();
    
    @Inject private UserService userService;
    
    @Inject private RoleService roleService;

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        if (req.getParameter("is_return") != null || Boolean.valueOf(req.getParameter("is_return"))) {
            HttpSession session = req.getSession();
            DiscoveryInformation discoveryInformation = (DiscoveryInformation) session.getAttribute("DISCOVERY_INFORMATION");
            Map<String, String> returnMap = OpenIdConsumer.processReturn(discoveryInformation, req.getParameterMap());
            if (returnMap == null || returnMap.isEmpty()) {
                // Oops, something went wrong. Display a message on the screen.
                // Check the logs for more information.
                logger.error("Open ID Confirmation Failed. No information was retrieved from the OpenID Provider.");
                resp.sendRedirect("home.jsf?loggin_error=true");
            } else {
                try {
                    String email = returnMap.get("email");
                    String fullName = returnMap.get("fullName");
                    // Check exist user
                    User user = userService.findUserByEmail(email);
                    if (user == null) {
                        userService.createCustomer(email, fullName);
                    }
                    session.setAttribute("LOGGED_USER", user);
                    
                    // Get roles of logged user
                    
                    List<Role> roleList = this.roleService.findRolesByUserEmail(email);
                    
                    session.setAttribute("LOGGED_USER_ROLES", new HashSet<Role>(roleList));
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                    resp.sendRedirect("home.jsf?loggin_error=true");
                }
                resp.sendRedirect("home.jsf");
            }
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String userSuppliedIdentifier = "";
        if (req.getParameter("identifier") != null) {
            userSuppliedIdentifier = (String) req.getParameter("identifier");
        } else {
            userSuppliedIdentifier = (String) req.getAttribute("identifier");
        }
        // Delegate to Open ID code
        DiscoveryInformation discoveryInformation = OpenIdConsumer.performDiscoveryOnUserSuppliedIdentifier(userSuppliedIdentifier);
        // Store the disovery results in session.
        HttpSession session = req.getSession();
        session.setAttribute("DISCOVERY_INFORMATION", discoveryInformation);
        
        // Create the AuthRequest
        AuthRequest authRequest = OpenIdConsumer.createOpenIdAuthRequest(userSuppliedIdentifier, discoveryInformation, returnToUrl);
        // Now take the AuthRequest and forward it on to the OP
        resp.sendRedirect(authRequest.getDestinationUrl(true));
    }
}
